﻿using Castle.Core.Logging;
using Inovout.Kuajing.Models;
using Inovout.Kuajing.Services;
using Inovout.Services;
using Inovout.Web.Http;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net.Http.Formatting;
using System.Text;
using System.Web.Http;

namespace Inovout.Kuajing.Web.Controllers
{
    public class NetStoreController : BaseHttpController
    {
        private IRepositoryService<LogisticsLog> logisticsLogService = ComponentRegistry.Resolve<IRepositoryService<LogisticsLog>>();
        private static ILogger logger;
        private ShipmentOrderService shipmentOrderService;
        static NetStoreController()
        {
            logger = ComponentRegistry.Resolve<ILoggerFactory>().Create(typeof(NetStoreController));
        }

        public NetStoreController()
        {
            this.shipmentOrderService = ComponentRegistry.Resolve<ShipmentOrderService>();

        }

        [Route("netstore/order")]
        public JObject OrderStatus(FormDataCollection body)
        {
            string notify_type = body["notify_type"];
            JObject data = JObject.Parse(body["data"]);
            string orderCode = (string)data["orderCode"];

            JObject result = new JObject();
            if (notify_type.Equals("WMS_ORDER_STATUS_UPLOAD"))
            {
                this.ProcessShipped(data);
            }
            else if (notify_type.Equals("UNLOAD_LOGISTICS_INFO"))
            {
                result["logisticsTrackResultList"] = this.ProcessLogistics(data);

            }
            else
            {
                this.ProcessShipping(data);
           }


            result["success"] = 1;
            StringBuilder builder = new StringBuilder(Environment.NewLine);
            builder.AppendLine("===========Request:" + notify_type + "========");
            builder.AppendLine(body["data"]);
            builder.AppendLine("=============response=:" + orderCode + "=====");
            builder.AppendLine(result.ToString());
            builder.AppendLine("============================");
            logger.Info(builder.ToString());
            return result;
        }
        private JArray ProcessLogistics(JObject data)
        {
            JArray logisticsTrackList = (JArray)data["logisticsTrackList"];
            List<JObject> results = new List<JObject>();
            foreach (var trace in logisticsTrackList)
            {
                LogisticsLog logisticsLog = new LogisticsLog();
                logisticsLog.TrackKey = (string)trace["trackKey"];
                logisticsLog.LogisticsOrderNo = (string)trace["tmsOrderCode"];
                logisticsLog.OperationDate = (DateTime)trace["operationDate"];
                logisticsLog.OperationAddress = (string)trace["operationAddress"];
                logisticsLog.OperationRemark = (string)trace["operationRemark"];
                logisticsLogService.Save(logisticsLog);
                JObject result = new JObject();
                result["trackKey"] = logisticsLog.TrackKey;
                result["isSuccess"] = true;
                results.Add(result);
            }
            return JArray.FromObject(results);

        }

        private void ProcessShipped(JObject data)
        {
            string orderCode = (string)data["orderCode"];
            ShipmentOrder order = this.shipmentOrderService.GetByNo(orderCode);
            order.Status = ShipmentOrderStatus.Shipped;
            this.shipmentOrderService.Update(order);
        }

        private void ProcessShipping(JObject data)
        {
            string orderCode = (string)data["orderCode"];
            string status = (string)data["status"];
            string tmsOrderCode = (string)data["tmsOrderCode"];
            string tmsServiceCode = (string)data["tmsServiceCode"];

            ShipmentOrder order = this.shipmentOrderService.GetByNo(orderCode);
            JToken weightToken;
            if (data.TryGetValue("weight", out weightToken))
            {
                order.ExpectedWeight = (float)weightToken;
            }

            if (!string.IsNullOrEmpty(tmsOrderCode))
            {
                order.LogisticsOrderNo = tmsOrderCode;
            }


            if (string.IsNullOrEmpty(tmsServiceCode))
            {
                order.LogisticsCompanyCode = tmsServiceCode;
            }
            switch (status)
            {
                case "WMS_ACCEPT":
                    order.Status = ShipmentOrderStatus.Packeging;
                    this.shipmentOrderService.Update(order);

                    break;
                case "WMS_PRINT":
                    order.Status = ShipmentOrderStatus.Packaged;
                    this.shipmentOrderService.Update(order);
                    break;
                case "WMS_PICK":
                    this.shipmentOrderService.Determine(order);
                    break;
            }
        }
    }
}
